package site.xuqing.autohelperengine;

import android.content.Context;
import android.view.accessibility.AccessibilityNodeInfo;

import java.util.ArrayList;
import java.util.List;

import site.xuqing.autohelper.bean.StepBean;
import site.xuqing.autohelper.bean.StepContainerBean;
import site.xuqing.autohelper.listener.OnStepListener;
import site.xuqing.autohelper.util.StringUtil;
import site.xuqing.autohelperengine.constant.Constant;
import site.xuqing.autohelperengine.listener.OnCurrentScreenDataListener;
import site.xuqing.autohelperengine.local.bean.StepLocalBean;
import site.xuqing.autohelperengine.local.bean.StepLocalSaveBean;
import site.xuqing.autohelperengine.local.overlay.FloatViewManager;
import site.xuqing.autohelperengine.local.util.StepSaveUtil;
import site.xuqing.autohelperengine.util.AppUtil;
import site.xuqing.autohelperengine.util.AuthorityUtil;
import site.xuqing.autohelperengine.util.ScreenUtil;

/**
 * @author XuQing
 */
public class AutoHelper {
    private static AutoHelper autoHelper;
    private OnStepListener onStepListener;
    private OnCurrentScreenDataListener onCurrentScreenDataListener;
    private boolean nextScreenNotExecute = false;
    private boolean isScreenDataStart = false;
    
    private AutoHelper() {}
    
    public static AutoHelper getInstance() {
        if (autoHelper == null) {
            autoHelper = new AutoHelper();
        }
        return autoHelper;
    }
    
    /**
     * 必须在Application中提前调用该方法初始化，否则无法使用服务
     *
     * @param context Context
     */
    public void init(Context context) {
        ScreenUtil.getInstance().init(context);
        FloatViewManager.getInstance().init(context);
        StepSaveUtil.init(context.getApplicationContext());
    }
    
    public OnStepListener getOnStepListener() {
        return onStepListener;
    }
    
    public void setOnStepListener(OnStepListener onStepListener) {
        this.onStepListener = onStepListener;
    }
    
    public boolean checkOverlayPermission(Context context) {
        return AuthorityUtil.hasOverlayPermission(context);
    }
    
    public boolean checkServicePermission(Context context) {
        return AuthorityUtil.isServiceRunning(context);
    }
    
    public void authorize(Context context) {
        AuthorityUtil.goAuthorityActivity(context);
    }
    
    public void authorize(Context context, boolean isNeedOverlayPermission, boolean isNeedAccessibilityPermission) {
        AuthorityUtil.goAuthorityActivity(context, isNeedOverlayPermission, isNeedAccessibilityPermission);
    }
    
    public boolean checkAuthorityAndAuthorize(Context context) {
        if (AuthorityUtil.hasAuthority(context)) {
            return true;
        } else {
            try {
                onStepListener.onStepScriptExecuteFinish(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            AuthorityUtil.goAuthorityActivity(context);
        }
        return false;
    }
    
    public void gotoDesktop(Context context) {
        AppUtil.gotoDesktop(context);
    }
    
    public void startAppByAppName(Context context, String appName) {
        if (!StringUtil.isEmptyString(appName)) {
            AppUtil.startAppByAppName(context, appName);
        }
    }
    
    public void startApp(Context context, String packageName) {
        if (!StringUtil.isEmptyString(packageName)) {
            AppUtil.startAPP(context, packageName);
        }
    }
    
    public void startAppAndExecuteStep(Context context, StepContainerBean stepContainerBean) {
        if (AutoHelper.getInstance().checkAuthorityAndAuthorize(context)) {
            startApp(context, stepContainerBean.getPackageName());
            StepManager.setSteps(stepContainerBean, onStepListener);
            StepManager.executeStart();
        }
    }
    
    public void executeStep(Context context, StepContainerBean stepContainerBean) {
        if (AutoHelper.getInstance().checkAuthorityAndAuthorize(context)) {
            StepManager.setSteps(stepContainerBean, onStepListener);
            StepManager.executeStart();
        }
    }
    
    public void executeStep(Context context, StepLocalSaveBean stepLocalSaveBean) {
        if (AutoHelper.getInstance().checkAuthorityAndAuthorize(context)) {
            StepManager.setLocalSteps(stepLocalSaveBean);
            StepManager.executeStart();
        }
    }
    
    public void executeStep(Context context, StepBean stepBean) {
        List<StepBean> stepBeans = new ArrayList<>();
        stepBeans.add(stepBean);
        executeStep(context, stepBeans);
    }
    
    public void executeStep(Context context, List<StepBean> stepBeans) {
        if (AutoHelper.getInstance().checkAuthorityAndAuthorize(context)) {
            StepContainerBean stepContainerBean = new StepContainerBean();
            stepContainerBean.setStepBeans(stepBeans);
            StepManager.setSteps(stepContainerBean, onStepListener);
            StepManager.executeStart();
        }
    }
    
    /**
     * 设置屏幕切换的屏幕数据
     *
     * @param root                   屏幕的AccessibilityNodeInfo
     * @param currentScreenClassName 当前屏幕所处的界面包名
     */
    public void setCurrentScreenData(AccessibilityNodeInfo root, String currentScreenClassName) {
        if (isScreenDataStart) {
            if (!nextScreenNotExecute) {
                if (onCurrentScreenDataListener != null) {
                    onCurrentScreenDataListener.onResult(root, currentScreenClassName);
                }
            } else {
                nextScreenNotExecute = false;
            }
        }
    }
    
    /**
     * 设置屏幕切换的监听
     *
     * @param onCurrentScreenDataListener 监听
     */
    public void setOnCurrentScreenDataListener(OnCurrentScreenDataListener onCurrentScreenDataListener) {
        this.onCurrentScreenDataListener = onCurrentScreenDataListener;
    }
    
    /**
     * 设置下一次屏幕切换不执行OnCurrentScreenDataListener回调
     */
    public void setNextScreenNotExecuteOnCurrentScreenDataListener() {
        nextScreenNotExecute = true;
    }
    
    /**
     * 是否允许执行ScreenData获取
     *
     * @param isStart 允许状态
     */
    public void setScreenDataStart(boolean isStart) {
        this.isScreenDataStart = isStart;
    }
    
    public void showStartMenuView(StepLocalSaveBean stepLocalSaveBean) {
        FloatViewManager.getInstance().showStartMenuView(stepLocalSaveBean);
    }
    
    public void showCreateMenuView(StepLocalBean stepLocalBean) {
        FloatViewManager.getInstance().showCreateMenuView(stepLocalBean);
    }
    
    public void hideMenuView() {
        FloatViewManager.getInstance().hideMenuView();
    }
    
    public void showLog(boolean show) {
        Constant.SHOW_LOG = show;
    }
    
    public void showErrorMsg(boolean show) {
        Constant.SHOW_MSG = show;
    }
}
